﻿using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.ComponentModel;

namespace Vit.Utils.Extensions
{
    public static class ObjectExtensions
    {
        public static T ConvertTo<T>(this object obj, T defaultValue)
        {
            if (obj == null || obj == DBNull.Value)
                return defaultValue;

            if (typeof(T).IsEnum)
            {
                int val = -1;
                if (int.TryParse(obj.ToString(), out val))
                {
                    return (T)((object)val);
                }
                else
                {
                    return (T)Enum.Parse(typeof(T), obj.ToString());
                }
            }
            else if (typeof(Guid).IsAssignableFrom(typeof(T)))
            {
                return (T)(new Guid(obj.ToString()) as object);
            }
            else if (typeof(bool).IsAssignableFrom(typeof(T)))
            {
                switch (obj.ToString().ToLower())
                {
                    case "on":
                    case "yes":
                    case "1":
                    case "true":
                        return (T)(true as object);
                    default:
                        return (T)(false as object);
                }
            }
            else
            {
                try
                {
                    return (T)obj;
                }
                catch
                {
                    try
                    {
                        return (T)Convert.ChangeType(obj, typeof(T));
                    }
                    catch { }
                }
            }
            return defaultValue;
        }

        public static T OrEquals<T>(this T obj, T obj2)
        {
            if (typeof(T).Equals(typeof(String)))
            {
                return OrEquals<T>(obj, obj2, (o) => o != null && !string.IsNullOrEmpty(o.ToString()));
            }
            return OrEquals<T>(obj, obj2, (o) => o != null);
        }

        public static T OrEquals<T>(this T obj, T obj2, Func<T, bool> predicate)
        {
            if (predicate(obj))
                return obj;
            else
                return obj2;
        }

        public static object OrEquals(this object obj, object obj2)
        {
            return OrEquals(obj, obj2, (o) => o != null);
        }

        public static object OrEquals(this object obj, object obj2, Func<object, bool> predicate)
        {
            if (predicate(obj))
                return obj;
            else
                return obj2;
        }
    }
}
